package cqrtplm.adapter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import cqrtplm.entity.oa.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class OAAdapter {

    @Resource
    private RestTemplate restTemplate;

    @Value("${oa.api.baseUrl:http://192.168.102.1:7003/OASystem/OaApi}")
    private String oaBaseUrl;

    @Value("${oa.api.createFlow:/CreateFlowNew}")
    private String createFlowPath;

    @Value("${oa.api.deleteFlow:/DeleteFlow}")
    private String deleteFlowPath;

    @Value("${oa.api.uploadFile:/UploadFile}")
    private String uploadFilePath;

    @Value("${oa.api.getEnums:/GetEnums}")
    private String getEnumsPath;

    /**
     * 创建OA流程 V8.0版本
     */
    public OACreateRetEntity CreateOAFlowV80(V80FlowDataModel flowData) {
        return CreateOAFlowV80(flowData, "", "", "", "");
    }

    /**
     * 创建OA流程 V8.0版本 (带日志参数)
     */
    public OACreateRetEntity CreateOAFlowV80(V80FlowDataModel flowData, String logTitle,
                                             String businessId, String businessCode, String createUserName) {
        try {
            log.info("开始发起OA流程 - {}, 业务ID: {}, 业务编码: {}, 创建人: {}",
                     logTitle, businessId, businessCode, createUserName);

            // 构造请求参数
            Map<String, Object> requestParam = new HashMap<>();

            // 将flowData转换为JSON字符串
            String flowDataJson = JSON.toJSONString(flowData);

            // 构造最终的请求数据
            Map<String, String> postDataMap = new HashMap<>();
            postDataMap.put("FlowData", flowDataJson);

            requestParam.put("postData", JSON.toJSONString(postDataMap));

            log.info("OA请求参数: {}", JSON.toJSONString(requestParam));

            // 发送HTTP请求
            String url = oaBaseUrl + createFlowPath;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestParam, headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

            log.info("OA响应状态: {}, 响应内容: {}", response.getStatusCode(), response.getBody());

            if (response.getStatusCode() == HttpStatus.OK && !StringUtils.isEmpty(response.getBody())) {
                // 解析响应结果
                OACreateRetEntity result = JSON.parseObject(response.getBody(), OACreateRetEntity.class);

                if ("0".equals(result.getCode())) {
                    log.info("OA流程创建成功 - {}, 流程ID: {}, 协同ID: {}",
                             logTitle,
                             result.getData() != null ? result.getData().getProcessId() : "",
                             result.getData() != null && result.getData().getAppbussinessdata() != null ?
                                     result.getData().getAppbussinessdata().getSummaryId() : "");
                } else {
                    log.error("OA流程创建失败 - {}, 错误码: {}, 错误信息: {}",
                              logTitle, result.getCode(), result.getMessage());
                }

                return result;
            } else {
                throw new RuntimeException("OA接口调用失败，HTTP状态码: " + response.getStatusCode());
            }

        } catch (Exception e) {
            log.error("调用OA接口异常 - {}, 业务ID: {}, 错误信息: {}", logTitle, businessId, e.getMessage(), e);
            throw new RuntimeException("调用OA接口失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除/撤销OA流程
     */
    public OADeleteRetEntity DeleteOAFlow(String flowId, String reason) {
        try {
            log.info("开始撤销OA流程, 流程ID: {}, 撤销原因: {}", flowId, reason);

            Map<String, Object> requestParam = new HashMap<>();
            requestParam.put("flowId", flowId);
            requestParam.put("reason", reason);

            String url = oaBaseUrl + deleteFlowPath;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestParam, headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

            log.info("撤销OA流程响应: {}", response.getBody());

            if (response.getStatusCode() == HttpStatus.OK && !StringUtils.isEmpty(response.getBody())) {
                OADeleteRetEntity result = JSON.parseObject(response.getBody(), OADeleteRetEntity.class);

                if ("0".equals(result.getCode())) {
                    log.info("OA流程撤销成功, 流程ID: {}", flowId);
                } else {
                    log.error("OA流程撤销失败, 流程ID: {}, 错误信息: {}", flowId, result.getMessage());
                }

                return result;
            } else {
                throw new RuntimeException("撤销OA流程失败，HTTP状态码: " + response.getStatusCode());
            }

        } catch (Exception e) {
            log.error("撤销OA流程异常, 流程ID: {}, 错误信息: {}", flowId, e.getMessage(), e);
            throw new RuntimeException("撤销OA流程失败: " + e.getMessage(), e);
        }
    }

    /**
     * 上传文件到OA系统
     */
    public Tuple<Boolean, String> UploadFlieByOA(String filePath, String fileName) {
        try {
            log.info("开始上传文件到OA, 文件路径: {}, 文件名: {}", filePath, fileName);

            File file = new File(filePath);
            if (!file.exists()) {
                log.error("文件不存在: {}", filePath);
                return new Tuple<>(false, "文件不存在");
            }

            // 构造多部分表单请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            // 这里需要根据实际OA接口的文件上传格式来调整
            // 通常需要使用MultiValueMap来构造multipart/form-data请求

            String url = oaBaseUrl + uploadFilePath;

            // 简化示例，实际实现需要根据OA接口文档调整
            Map<String, Object> requestParam = new HashMap<>();
            requestParam.put("fileName", fileName);
            requestParam.put("fileData", Files.readAllBytes(file.toPath()));

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestParam, headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

            if (response.getStatusCode() == HttpStatus.OK && !StringUtils.isEmpty(response.getBody())) {
                JSONObject result = JSON.parseObject(response.getBody());

                if ("0".equals(result.getString("code"))) {
                    String fileId = result.getString("fileId");
                    log.info("文件上传成功, 文件ID: {}", fileId);
                    return new Tuple<>(true, fileId);
                } else {
                    log.error("文件上传失败: {}", result.getString("message"));
                    return new Tuple<>(false, result.getString("message"));
                }
            } else {
                return new Tuple<>(false, "上传失败");
            }

        } catch (Exception e) {
            log.error("上传文件到OA异常, 文件路径: {}, 错误信息: {}", filePath, e.getMessage(), e);
            return new Tuple<>(false, e.getMessage());
        }
    }

    /**
     * 获取OA枚举值
     */
    public List<OAEnumEntity> GetOAEnums(String param1, String enumNames) {
        try {
            log.info("开始获取OA枚举值, 参数1: {}, 枚举名称: {}", param1, enumNames);

            Map<String, Object> requestParam = new HashMap<>();
            requestParam.put("param1", param1);
            requestParam.put("enumNames", enumNames);

            String url = oaBaseUrl + getEnumsPath;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestParam, headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

            if (response.getStatusCode() == HttpStatus.OK && !StringUtils.isEmpty(response.getBody())) {
                JSONObject result = JSON.parseObject(response.getBody());

                if ("0".equals(result.getString("code"))) {
                    List<OAEnumEntity> enumList = JSON.parseArray(result.getString("data"), OAEnumEntity.class);
                    log.info("获取OA枚举值成功, 数量: {}", enumList != null ? enumList.size() : 0);
                    return enumList;
                } else {
                    log.error("获取OA枚举值失败: {}", result.getString("message"));
                    throw new RuntimeException("获取OA枚举值失败: " + result.getString("message"));
                }
            } else {
                throw new RuntimeException("获取OA枚举值失败，HTTP状态码: " + response.getStatusCode());
            }

        } catch (Exception e) {
            log.error("获取OA枚举值异常, 错误信息: {}", e.getMessage(), e);
            throw new RuntimeException("获取OA枚举值失败: " + e.getMessage(), e);
        }
    }

    /**
     * 简单的元组类，用于返回两个值
     */
    public static class Tuple<T1, T2> {
        private T1 item1;
        private T2 item2;

        public Tuple(T1 item1, T2 item2) {
            this.item1 = item1;
            this.item2 = item2;
        }

        public T1 getItem1() {
            return item1;
        }

        public T2 getItem2() {
            return item2;
        }
    }
}
